/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package proy1sistdistribuidos.modelo;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Observer;
import proy1sistdistribuidos.interfaz.BuscarContenidoInicio;

/**
 * @author Carlos Diaz Maya, Juan Felipe Garcia
 */
public class ControladorProySistDistribuidos {
    private AdministradorJXTA administrador;
    private String idUsuario;
    public static final String rutaCarpetaDescarga = "./RepositorioImagenes/";

    public ControladorProySistDistribuidos(String idUsuario) throws Exception {
        administrador = new AdministradorJXTA(idUsuario);
        administrador.publicarNodo();

        File carp = new File(rutaCarpetaDescarga);
        if(!carp.exists())
            carp.mkdirs();
        FileFilter filtro = new FileFilter() {
            public boolean accept(File ruta) {
                boolean aceptado = false;
                String nomArch = ruta.getName();
                String[] partesNom = nomArch.split("\\.");

                if(partesNom.length > 1){
                    String extension = partesNom[partesNom.length-1];
                    if(extension.equalsIgnoreCase("png") ||
                       extension.equalsIgnoreCase("gif") ||
                       extension.equalsIgnoreCase("jpg") ||
                       extension.equalsIgnoreCase("jpeg")) {
                        return true;
                    } else return false;
                } else return false;
            }
        };

        //Publica todos los archivos ofrecidos por el usuario
        File[] archivos = carp.listFiles(filtro);

        for(File archivo:archivos){
            String nomArch = archivo.getName();
            String[] partesNom = nomArch.split("\\."); 
            File archivoInfoPersonas = new File(rutaCarpetaDescarga+partesNom[0]+".ips");
            List<String[]> personas = new LinkedList<String[]>();
            if(!archivoInfoPersonas.exists()){
                personas = null;
            } else {
                FileReader fil = new FileReader(archivoInfoPersonas);
                BufferedReader lector = new BufferedReader(fil);
                String linea = null;
                while((linea=lector.readLine())!=null){
                    String[] info = linea.split(";");
                    if(info.length>=2){
                        String[] result = new String[2];
                        result[0] = info[0];
                        result[1] = info[1];
                        personas.add(result);
                    }
                }
                lector.close();
                fil.close();
            }
            administrador.publicarImagen(partesNom[0], personas, archivo);
        }

    }

    public void buscarArchivosPorEtiqueta(String etiqueta) {
       administrador.buscarArchivosPorEtiqueta(etiqueta);
    }

    public void buscarArchivosPorPersonas(List<String[]> personas){
        administrador.buscarImagenesPorNombresPersonas(personas);
    }
    
    public void buscarFotoMasParecidaAImagen(byte[] imagenDada) throws IOException{
        administrador.buscarFotoMasParecidaAImagen(imagenDada);
    }

    public void obtenerInformacionImagen(String idEtiqueta) {
        administrador.obtenerInformacionImagen(idEtiqueta);
    }

    public void publicarImagen(String etiqueta, List<String[]> personas, File archivo) throws Exception {
        administrador.publicarImagen(etiqueta, personas, archivo);
    }

    public File[] obtenerArchivosImagenDescargados() {
      File carp = new File(rutaCarpetaDescarga);
        if(!carp.exists())
            carp.mkdirs();
        FileFilter filtro = new FileFilter() {
            public boolean accept(File ruta) {
                boolean aceptado = false;
                String nomArch = ruta.getName();
                String[] partesNom = nomArch.split("\\.");

                if(partesNom.length > 1){
                    String extension = partesNom[partesNom.length-1];
                    if(extension.equalsIgnoreCase("png") ||
                       extension.equalsIgnoreCase("gif") ||
                       extension.equalsIgnoreCase("jpg") ||
                       extension.equalsIgnoreCase("jpeg")) {
                        return true;
                    } else return false;
                } else return false;
            }
        };

         //Publica todos los archivos ofrecidos por el usuario
        File[] archivos = carp.listFiles(filtro);

        return archivos;
    }

    public List<String[]> obtenerInformacionArchivoInfPersonas(File archivo) throws Exception {
        List<String[]> personas = null;
        String nomArch = archivo.getName();
        String[] partesNom = nomArch.split("\\.");
        File archivoInfoPersonas = new File(rutaCarpetaDescarga+partesNom[0]+".ips");
        if(!archivoInfoPersonas.exists()){
            personas = null;
        } else {
            personas = new ArrayList<String[]>();
            FileReader fil = new FileReader(archivoInfoPersonas);
            BufferedReader lector = new BufferedReader(fil);
            String linea = null;
            while((linea=lector.readLine())!=null){
                String[] info = linea.split(";");
                if(info.length>=2){
                    String[] result = new String[2];
                    result[0] = info[0];
                    result[1] = info[1];
                    personas.add(result);
                }
            }
            lector.close();
            fil.close();
        }
        return personas;
    }

    public List<String> obtenerInformacionArchivoInfDescarga(File archivo) throws Exception {
        List<String> infoArchivo = null;
        String nomArch = archivo.getName();
        String[] partesNom = nomArch.split("\\.");
        File archivoInfoDescarga = new File(rutaCarpetaDescarga+partesNom[0]+".iim");
        if(!archivoInfoDescarga.exists()){
            infoArchivo = null;
        } else {
            infoArchivo = new ArrayList<String>();
            FileReader fil = new FileReader(archivoInfoDescarga);
            BufferedReader lector = new BufferedReader(fil);
            String linea = null;
            while((linea=lector.readLine())!=null){
               infoArchivo.add(linea);
            }
            lector.close();
            fil.close();
        }
        return infoArchivo;
    }

    
     public void addObserver(Observer ob){
        administrador.addObserver(ob);
    }

    public String calcularHashEtiqueta(String idEtiqueta) throws NoSuchAlgorithmException {
       //----Inicio codigo creacion hash ----
            //Adaptado del codigo disponible en:
            //http://www.mkyong.com/java/java-sha-hashing-example/
            //para su uso en este proyecto.

            //Se crea un indice SHA-256 con base a la etiqueta
            //
            MessageDigest md = MessageDigest.getInstance("SHA-256");

            byte[] etiquetaEnBytes = idEtiqueta.getBytes();
            //Se pasa el arreglo al "digester" para que la pase a SHA-256
            md.update(etiquetaEnBytes);

            //Se guarda el resultado en otro arreglo de bytes
            byte[] arrbtDigest = md.digest();


            //Lineas tomadas directamente del ejemplo disponible en
            //http://www.mkyong.com/java/java-sha-hashing-example/
            //donde se pasa el hash a formato hexadecimal
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < arrbtDigest.length; i++) {
                sb.append(Integer.toString((arrbtDigest[i] & 0xff) + 0x100, 16).substring(1));
            }

            String indiceEtiqueta = sb.toString();
            //--- Fin código creación hash
            return indiceEtiqueta;
    }

    public void removeObserver(Observer aThis) {
        administrador.deleteObserver(aThis);
    }

}
